In the previous exercise, we already have created our first loop using an if-else statement. Here we want to deepen our understanding of loops and apply some more of them.

1

Take the list you have created in the previous exercise. Use your fancy function to check whether an object is numeric and apply it to each of the list elements. Use a for() loop for this purpose.
When your list is not in your environment anymore, you have to re-create it again. Check out our solution if you want to use a hideous one. Oh… the same applies to the function.
# re-create list
cool_numeric_vector <- sample(1:5, 5, replace = TRUE)

cool_character_vector <- c("yeah", "arrrr", "eins11", 0815, "blubb")

cool_matrix <- matrix(1:32, nrow = 4)

cool_list <- list(c(1:3), NA, "huhu")

cool_global_list <-
  list(
    cool_numeric_vector,
    cool_character_vector,
    cool_matrix,
    cool_list
  )

# re-create function
numeric_checker <- function (x) {
  if (is.numeric(x)) {
    print("Indeed. This is a numeric vector.")
  } else {
    print("I am afraid I have to tell you the vector is not numeric :-(")
  }
}

# iterate through list with a for loop
for(element in cool_global_list) {
  numeric_checker(element)
}
## [1] "Indeed. This is a numeric vector."
## [1] "I am afraid I have to tell you the vector is not numeric :-("
## [1] "Indeed. This is a numeric vector."
## [1] "I am afraid I have to tell you the vector is not numeric :-("

for() loops are nice, but there are alternatives, right?

2

Now use the lapply() function to iterate through the list - do you see any differences to the for() call?
Look at the number of elements to search for differences.
lapply(cool_global_list, numeric_checker)
## [1] "Indeed. This is a numeric vector."
## [1] "I am afraid I have to tell you the vector is not numeric :-("
## [1] "Indeed. This is a numeric vector."
## [1] "I am afraid I have to tell you the vector is not numeric :-("
## [[1]]
## [1] "Indeed. This is a numeric vector."
## 
## [[2]]
## [1] "I am afraid I have to tell you the vector is not numeric :-("
## 
## [[3]]
## [1] "Indeed. This is a numeric vector."
## 
## [[4]]
## [1] "I am afraid I have to tell you the vector is not numeric :-("
# Difference:
# The difference is that for() only iterates through the first level, lapply() 
# through all of them

To conclude this exercise, let’s turn to code styling. For this purpose, look at this code fragment here:

mean(sqrt(as.numeric(data.frame(id = 1, age = "20")$age)))

3

What do you think the command does?
It’s always an excellent approach to start reading/interpreting code from the central/inner command and continue to the outer ones.
  1. A single-row data frame is created
  2. Only the age variable is extracted using the $ operator
  3. The variable is converted to the numeric format with as.numeric()
  4. A square root transformation is applied with sqrt()
  5. The mean is calculated with mean()

Using the commands in such a way makes the code somewhat challenging to read and understand. You should have learned that pipes provide a straightforward approach to address this issue.

4

Create a pipe from this nested command.
You can call individual columns of a piped object with .$col_name here.
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
data.frame(id = 1, age = "20") %>% 
  .$age %>% 
  as.numeric() %>% 
  sqrt() %>% 
  mean()
## [1] 4.472136